# 合并图片
import os
from PIL import Image
import re

def get_image_number(filename):
  """
  从文件名中提取数字
  :param filename: 文件名
  :return: 提取到的数字，如果没有则返回 -1
  """
  match = re.search(r'_(\d+)\.\w+', filename)
  if match:
    return int(match.group(1))
  return -1

def combine_images(directory):
  """
  读取指定目录下的图片，按名称中的数字升序排列后拼接成一张长图
  每张图片将被调整为最大宽度和最大高度
  :param directory: 图片所在目录
  """
  # 获取目录下所有图片文件
  image_files = [f for f in os.listdir(directory) if f.lower().endswith(('.png', '.jpg', '.jpeg'))]
  # 按文件名中的数字升序排序
  image_files.sort(key = get_image_number)

  if not image_files:
    print("目录中没有找到图片文件")
    return

  images = []
  max_width = 0
  max_height = 0

  # 打开所有图片，计算最大宽度和最大高度
  for image_file in image_files:
    image_path = os.path.join(directory, image_file)
    try:
      image = Image.open(image_path)
      images.append(image)
      max_width = max(max_width, image.width)
      max_height = max(max_height, image.height)
    except Exception as e:
      print(f"无法打开图片 {image_file}: {e}")

  if not images:
    print("没有有效的图片可以处理")
    return

  # 创建一个空白的长图
  combined_image = Image.new('RGB', (max_width, max_height * len(images)))
  current_height = 0

  # 将每张图片调整大小后粘贴到长图上
  for i, image in enumerate(images):
    # 调整图片大小到最大宽度和高度，保持原比例，空白部分填充白色
    resized_image = Image.new('RGB', (max_width, max_height), (255, 255, 255))
    # 计算缩放比例，保持原图比例
    ratio = min(max_width / image.width, max_height / image.height)
    new_size = (int(image.width * ratio), int(image.height * ratio))
    resized_img = image.resize(new_size, Image.Resampling.LANCZOS)
    # 将缩放后的图片居中放置
    x_offset = (max_width - new_size[0]) // 2
    y_offset = (max_height - new_size[1]) // 2
    resized_image.paste(resized_img, (x_offset, y_offset))

    # 将处理后的图片粘贴到长图上
    combined_image.paste(resized_image, (0, current_height))
    current_height += max_height
    print(f"已处理图片 {i + 1}/{len(images)}")

  # 获取目录名称
  dir_name = os.path.basename(os.path.normpath(directory))
  # 以目录名称作为文件名保存合并后的长图
  output_filename = f"{dir_name}_combined.jpg"
  output_path = os.path.join(directory, output_filename)

  try:
    combined_image.save(output_path, quality = 95)
    print(f"图片合并完成，合并后的图片已保存为 {output_filename}")
    print(f"合并后的图片尺寸: {combined_image.width} x {combined_image.height}")
  except Exception as e:
    print(f"保存合并图片时出错: {e}")

if __name__ == "__main__":
  directory = r'D:\360安全浏览器下载\新建文件夹'  # 请替换为实际的图片目录
  combine_images(directory)
